import re
import ezdxf
from openpyxl import load_workbook
import pandas as pd
import os
from shapely.geometry import box, Point


def extract_grid_lines(block, length_threshold=5):
    horizontal_lines = []
    vertical_lines = []

    for entity in block:
        if entity.dxftype() == "LINE":
            start = entity.dxf.start
            end = entity.dxf.end
            dx = abs(end.x - start.x)
            dy = abs(end.y - start.y)

            if dx >= length_threshold and dy < 1e-3:
                horizontal_lines.append((round(start.y, 2), start.x, end.x))
            elif dy >= length_threshold and dx < 1e-3:
                vertical_lines.append((round(start.x, 2), start.y, end.y))

    x_lines = sorted(set([x for x, _, _ in vertical_lines]))
    y_lines = sorted(set([y for y, _, _ in horizontal_lines]), reverse=True)
    return x_lines, y_lines


def extract_texts(block):
    texts = []
    for entity in block:
        if entity.dxftype() == "TEXT":
            x, y = entity.dxf.insert.x, entity.dxf.insert.y
            texts.append((x, y, entity.dxf.text.strip()))
        elif entity.dxftype() == "MTEXT":
            x, y = entity.dxf.insert.x, entity.dxf.insert.y
            texts.append((x, y, entity.text.strip()))
    return texts


def map_texts_to_cells(texts, x_lines, y_lines):
    table = [["" for _ in range(len(x_lines) - 1)] for _ in range(len(y_lines) - 1)]

    for x, y, text in texts:
        point = Point(x, y)
        for i in range(len(y_lines) - 1):
            for j in range(len(x_lines) - 1):
                cell = box(x_lines[j], y_lines[i + 1], x_lines[j + 1], y_lines[i])
                if cell.contains(point):
                    if table[i][j]:
                        table[i][j] += " | " + text
                    else:
                        table[i][j] = text
                    break
    return pd.DataFrame(table)


def extract_table_blocks_to_excel(dxf_path, output_excel,required_keywords=['导线终点', '导线起点', '设备型号', '设备厂家']):
    import shutil  # 防止文件残留用
    doc = ezdxf.readfile(dxf_path)
    found_tables = []

    required_keywords = required_keywords

    for block_name in doc.blocks.block_names():
        if block_name.startswith("*"):
            continue

        block = doc.blocks[block_name]
        x_lines, y_lines = extract_grid_lines(block)
        if len(x_lines) < 2 or len(y_lines) < 2:
            continue

        texts = extract_texts(block)
        df = map_texts_to_cells(texts, x_lines, y_lines)

        # 过滤条件：行数>=3 且列名含关键字
        if df.empty or len(df) < 4:
            print(f"⚠️ 表格块: {block_name} 行数小于4，已跳过")
            continue

        header_row = df.iloc[0].astype(str).tolist()
        if not any(any(keyword in cell for keyword in required_keywords) for cell in header_row):
            print(f"⚠️ 表格块: {block_name} 不含关键列名，已跳过")
            continue

        found_tables.append((block_name[:31], df, len(texts)))

    if found_tables:
        with pd.ExcelWriter(output_excel, engine="openpyxl") as writer:
            for sheet_name, df, text_count in found_tables:
                df.to_excel(writer, sheet_name=sheet_name, index=False, header=False)
                print(f"✅ 表格块: {sheet_name} 已提取，共 {text_count} 条文字")
        print(f"🎉 已保存到: {output_excel}")
    else:
        # 如果之前有残留空文件，删除它
        if os.path.exists(output_excel):
            try:
                os.remove(output_excel)
                print(f"🗑️ 删除空的 Excel 文件：{output_excel}")
            except Exception as e:
                print(f"⚠️ 删除文件失败：{output_excel}，错误：{e}")
        print(f"⚠️ 未找到任何符合条件的表格块，未生成 Excel 文件")


def clean_cell_content(text):
    """清理单元格内容：去除|和多余空格"""
    text = str(text).strip()  # 去除前后空格
    text = re.sub(r"\s+", " ", text)  # 多个空格合并
    text = text.replace("|", "")  # 去除管道符
    text = text.replace(" ", "")  # 删除所有空格
    text = re.sub(r"\u3000", "", text)  # 删除全角空格（中文空格），可选
    return text


def clean_excel_file(file_path):
    wb = load_workbook(file_path)

    for sheet_name in wb.sheetnames:
        ws = wb[sheet_name]
        print(f"处理工作表: {sheet_name}")

        for row in ws.iter_rows():
            for cell in row:
                if cell.value is not None and isinstance(cell.value, str):
                    cleaned = clean_cell_content(cell.value)
                    if cleaned != cell.value:
                        cell.value = cleaned

    wb.save(file_path)
    print(f"✅ 清理完成并保存: {file_path}")


def extract_tables_from_dxf(dxf_paths):
    """
    从 DXF 文件中提取表格块并保存到 Excel 文件。
    """
    output_excel_list = []
    for dxf_file in dxf_paths:
        output_dir = os.path.dirname(dxf_file)
        parent_dir = os.path.dirname(output_dir)

        # 创建保存目录
        retrieve_folder = os.path.join(parent_dir, "retrieve_folder")
        os.makedirs(retrieve_folder, exist_ok=True)

        # 构造 Excel 输出路径
        base_name = os.path.splitext(os.path.basename(dxf_file))[0]
        output_excel = os.path.join(retrieve_folder, base_name + "_tables.xlsx")
        # 提取表格并生成 Excel

        extract_table_blocks_to_excel(dxf_file, output_excel)

        # 判断是否生成 Excel 文件，避免打开失败
        if os.path.exists(output_excel) and os.path.getsize(output_excel) > 0:
            clean_excel_file(output_excel)
            output_excel_list.append(output_excel)
        else:
            print(f"⚠️ 文件未生成或为空，跳过清理：{output_excel}")
    return output_excel_list


if __name__ == "__main__":
    dxf_list = [
        "E:\cadsecond-processing\output\主要安全风险点及安全施工说明_1_20250718_084633_305.dxf",
        "E:\cadsecond-processing\output\无线基站位置示意图_2_20250718_084636_701.dxf",
        "E:\cadsecond-processing\output\海宁长安皮毛市场汇聚机房近端机房设备平面布置图_3_20250718_084640_063.dxf",
        "E:\cadsecond-processing\output\海宁长安皮毛市场汇聚机房线缆路由及GPS天线安装示意图_4_20250718_084643_583.dxf",
        "E:\cadsecond-processing\output\远端机房设备平面布置图_5_20250718_084647_061.dxf",
        "E:\cadsecond-processing\output\远端机房线缆路由图_6_20250718_084650_390.dxf",
        "E:\cadsecond-processing\output\远端基站天馈安装示意图_7_20250718_084653_992.dxf"

        # 其他 DXF 路径...
    ]
    l = extract_tables_from_dxf(dxf_list)
    print(l)




